import { Application, FrontendSession } from 'pinus';
import { AdWatchDone_req, EquipChange_revc, ExchangeEquip_req, PlayerLevel_revc, wxLogin_req } from '../../../package/protocol/ProtoDef';
import { Channel, SessionKey } from '../../../common/enum';

export default function (app: Application) {
    return new Handler(app);
}

export class Handler {
    constructor(private app: Application) {

    }

    /**
     * 处理玩家登录(这里是前端session需要自定义返回)
     *
     * @param  {Object}   msg     玩家登录信息
     * @param  {Object}   session current session object
     */
    async entry(msg: wxLogin_req, session: FrontendSession) {
        //1 获取用户基础信息
        const appid: string = msg.appid;
        const openid: string = msg.openid;
        const token: string = msg.token;
        //2 校验token,提交的信息是否正确
        if(openid === '') {
            return {code: 401, error: true};
        }
        //3 远程调用获取用户对应的角色信息
        let self = this;
        const playerId: number = await self.app.rpc.connector.authRemoter.auth(session, msg);
        //3.1 若当前用户在线则把上一次登录的踢下线
        let sessionService = self.app.get('sessionService');
        let exits = sessionService.getByUid(playerId.toString());
        if(exits) {
            exits.forEach((item) => item.set(SessionKey.RepeatedLogin, 1));
            await sessionService.akick(playerId.toString());
        }
        //3.2 用户标识与session绑定，这个是重点
        await session.abind(playerId.toString());
        //注册用户离线操作
        session.on('closed', await this.onUserLeave.bind(this));
        // 这定义数据写入session并且与后端服务器同步(push)
        session.set('playerObj',1000000);
        session.set('rid', Channel.Defult);
        session.push('rid', function (err) {
            if (err) {
                console.error('set rid for session service failed! error is : %j', err.stack);
            }
        });
        //将所有前端session所有数据同步到后端session
        session.pushAll(function(err, result) {
            console.log('-------')
            console.log(err,result)
        });
        //用户上线操作，将用户写入频道中
        let sid = self.app.get('serverId');
        await self.app.rpc.connector.authRemoter.add(session, playerId.toString(), sid, Channel.Defult, true);
        //4 前端服务器发送消息
        //4.1 广播消息
        const param = new ExchangeEquip_req();
        const channelSrv = self.app.get('channelService');
        const channel = channelSrv.getChannel(Channel.Defult, true);
        for (let i = 0; i < 1; i++) {
            channel.pushMessage('', param);    
        }
        //4.2 对指定用户发送消息
        const singleParam = new EquipChange_revc();
        let tuid = playerId.toString();
        let tsidInfo = channel.getMember(tuid);
        if(tsidInfo !== undefined && tsidInfo['sid'] !== undefined) {
            channelSrv.pushMessageByUids('', singleParam, [{
                uid: tuid,
                sid: tsidInfo['sid']
            }]);
        }
        return;
    }

    /**
     * User log out handler
     *
     * @param {Object} app current application
     * @param {Object} session current session object
     *
     */
    async onUserLeave(session: FrontendSession) {
        if (!session || !session.uid) {
            return;
        }
        const repeated = session.get(SessionKey.RepeatedLogin);
        //顶号的情况下可能不需要删除部分信息，可以在session中加入字段信息
        await this.app.rpc.connector.authRemoter.kick.route(session, true)(session.uid, this.app.get('serverId'), session.get('rid'));
    }

}